<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>旅游</title>

    <link
      rel="stylesheet"
      href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"
    />
    <link rel="stylesheet" href="./css/index.css" />
    <link rel="stylesheet" href="./css/banner.css" />
  </head>

  <body>
    <div id="app" @click="showOps=false">
      <div style="width: 70%; text-align: center; margin: auto">
        <div class="banner">
          <div class="logo">
            <img src="./img/heima.png" alt="1" />
            <span>
              <div class="logo-ch">旅游</div>
            </span>
          </div>
          <div>
            <input type="checkbox" id="toggle-button" v-model="isTest" />
            <!--label中的for跟input的id绑定。作用是在点击label时选中input或者取消选中input-->
            <label for="toggle-button" class="button-label">
              <span class="circle"></span>
              <span class="text on">测试</span>
              <span class="text off">正式</span>
            </label>
          </div>
        </div>
        <!--关键字搜索-->
        <div class="search-bar">
          <div class="input-box">
            <input
              title="输入关键字搜索酒店"
              v-model="params.key"
              type="text"
              @click.stop=""
              @focus="showOps=true"
              @keyup="handleKeyUp($event)"
            />
            <button @click="handleSearch">搜索</button>
          </div>
          <div id="complete-box" v-show="showOps && ops.length > 0">
            <div
              v-for="(item, i) in ops"
              :key="i"
              @click="handleSearch"
              @mouseover="opsIndex = i"
              :style='{"background-color": opsIndex===i ? "#EEE" : "#fff"}'
            >
              {{item}}
            </div>
          </div>
        </div>
        <!-- 已选择过滤项 -->
        <div class="selected-ops">
          <div class="open">全部结果：</div>
          <div
            class="selected-op"
            v-for="(v, k) in params.filters"
            :key="k"
            @click="deleteFilter(k)"
          >
            {{filterNames[k]}}：<span>{{v}} <span class="close">×</span></span>
          </div>
        </div>
        <!--过滤项-->
        <div class="filter-list">
          <div v-for="(v, k) in remainFilter" :key="k">
            <div class="filter-box">
              <div class="f-key"><strong>{{filterNames[k]}}</strong></div>
              <div class="column-divider"></div>
              <div class="f-items">
                <div
                  class="f-item"
                  @click="clickFilter(k, o)"
                  v-for="(o, j) in v"
                  :key="j"
                >
                  <a href="javascript:void(0)"> {{o}}</a>
                </div>
              </div>
            </div>
            <div class="row-divider"></div>
          </div>
          <div class="filter-box">
            <div class="f-key"><strong>价格</strong></div>
            <div class="column-divider"></div>
            <div class="f-items">
              <div class="f-item" @click="clickFilter('price','0-100')">
                <a href="javascript:void(0)">100元以下</a>
              </div>
              <div class="f-item" @click="clickFilter('price','100-300')">
                <a href="javascript:void(0)">100-300元</a>
              </div>
              <div class="f-item" @click="clickFilter('price','300-600')">
                <a href="javascript:void(0)">300-600元</a>
              </div>
              <div class="f-item" @click="clickFilter('price','600-1500')">
                <a href="javascript:void(0)">600-1500元</a>
              </div>
              <div class="f-item" @click="clickFilter('price','1500-0')">
                <a href="javascript:void(0)">1500元以上</a>
              </div>
            </div>
          </div>
        </div>
        <!-- 排序 -->
        <div class="top-ban">
          <!--排序条件-->
          <div class="sort-items">
            <div class="sort-item" v-for="(item, i) in sortItems" :key="i">
              <a
                :class="{selected: params.sortBy===item.key}"
                @click="params.sortBy=item.key"
                href="javascript:void(0)"
                >{{item.text}}</a
              >
              |
            </div>
          </div>

          <!--分页条-->
          <div class="top-pagination">
            <span>共 <i style="color: #222">{{total}}</i> 家酒店</span>
            <span><i style="color: red">{{params.page}}</i>/{{totalPage}}</span>
            <a
              class="btn-arrow"
              href="#"
              style="display: inline-block"
              @click="prePage"
              >&lt;</a
            >
            <a
              class="btn-arrow"
              href="#"
              style="display: inline-block"
              @click="nextPage"
              >&gt;</a
            >
          </div>
        </div>
        <div class="row-divider" style="margin-bottom: 5px; width: 100%"></div>
        <!--酒店列表-->
        <div style="display: flex; justify-content: space-between">
          <div class="hotel-list">
            <div
              class="hotel-box"
              v-for="(hotel,i) in hotels"
              :key="i"
              style="display: flex; justify-content: space-between"
              @mouseover="handleMarkerFocus(hotel)"
            >
              <div class="ad-mark" v-if="hotel.isAD">
                <img src="./img/ad.png" width="25" />
              </div>
              <div style="width: 0"></div>
              <div style="width: 25%">
                <img width="100%" :src="hotel.pic" />
              </div>
              <div class="hotel-info">
                <div class="hotel-name" v-html="hotel.name"></div>
                <div class="star-name">{{hotel.starName}}</div>
                <div class="address">
                  位于
                  <span style="color: #bc8516">{{hotel.business}}</span>
                  周边，{{hotel.address}}
                </div>
                <div class="order">1分钟前有人预订了该酒店</div>
                <div v-if="hotel.distance" class="address">
                  距离您 {{hotel.distance.toFixed(2)}} km
                </div>
              </div>
              <div style="text-align: left; width: 15%">
                <div>
                  <b style="color: #f60">￥</b>
                  <span id="hotel-price">{{hotel.price}}</span>
                  <span style="font-size: 0.2em; color: #999">起</span>
                </div>
                <div class="btn">立即预定</div>
                <div>
                  <span class="hotel-score">{{hotel.score / 10}}分</span> /<span
                    >5分</span
                  >
                </div>
              </div>
            </div>
          </div>
          <div
            :class='{"map-box": true, "fixed-map": isFixed}'
            :style="{left: ml + 'px'}"
          >
            <div class="map-head">地图预览</div>
            <div class="amap" id="container"></div>
            <div class="map-geo" @click="getGeoLoc">
              <img
                src="https://a.amap.com/jsapi/static/image/plugin/waite.png"
                v-show="loading"
              />
            </div>
          </div>
        </div>
      </div>
    </div>

    <script src="./js/vue.js"></script>
    <script src="./js/axios.min.js"></script>
    <script src="./js/amap.min.js"></script>
    <script
      type="text/javascript"
      src="https://webapi.amap.com/maps?v=2.0&key=ddd292c88aa1bad9c04891a47724f40a"
    ></script>

    <script>
      // 设置后台服务地址
      axios.defaults.baseURL = "http://localhost:10100/es";
      axios.defaults.timeout = 3000;

      let app = new Vue({
        el: "#app",
        data: {
          isTest: false,
          filterNames: {
            brand: "品牌",
            city: "城市",
            starName: "星级",
            price: "价格",
          },
          filterList: {}, // 过滤项的假数据
          sortItems: [
            {
              key: "id",
              text: "默认",
            },
            {
              key: "score",
              text: "评价",
            },
            {
              key: "price",
              text: "价格",
            },
          ], // 排序字段的假数据
          hotels: [], // 酒店数据
          total: 0, // 总条数
          totalPage: 0, // 总页数
          params: {
            key: "", // 搜索关键字
            page: 1, // 当前页码
            size: 5, // 每页大小
            sortBy: "id", // 排序字段
            filters: {}, // 过滤字段
          },
          map: {}, // 地图对象
          loc: "", // 地图标记
          ml: 0, // 控制地图位置
          geolocation: {}, // 定位系统
          loading: false, // 是否在定位
          currentHotel: {},
          ops: [],
          showOps: false,
          opsIndex: -1,
          isFixed: false,
          testFilterData: {
            city: ["上海", "北京", "深圳", "杭州"],
            starName: ["四星", "五星", "二钻", "三钻", "四钻", "五钻"],
            brand: [
              "7天酒店",
              "如家",
              "速8",
              "皇冠假日",
              "华美达",
              "万怡",
              "喜来登",
              "万豪",
              "和颐",
              "希尔顿",
            ],
          },
        },
        watch: {
          "params.sortBy"() {
            // 每当page改变，当前代码就会执行。搜索一下
            this.search(this.loc);
          },
          "params.page"() {
            // 每当page改变，当前代码就会执行。搜索一下
            this.search(this.loc);
          },
          "params.filters": {
            deep: true,
            handler() {
              this.search();
              // 获取过滤项
              this.getFilter();
            },
          },
          opsIndex() {
            if (this.opsIndex !== -1) {
              this.params.key = this.ops[this.opsIndex];
            }
          },
        },
        created() {
          // 页面加载时，先搜索一下
          this.search();
          // 获取过滤项
          this.getFilter();
        },
        mounted() {
          //初始化地图
          this.map = new AMap.Map("container", {
            resizeEnable: true, //是否监控地图容器尺寸变化
            zoom: 11, //初始地图级别
            center: [120.0, 32.0], //初始地图中心点
          });
          // 初始化定位系统
          AMap.plugin("AMap.Geolocation", () => {
            this.geolocation = new AMap.Geolocation({
              position: "RT", //定位按钮的停靠位置
              buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
              zoomToAccuracy: true, //定位成功后是否自动调整地图视野到定位点
            });

            // AMap.Event.addListener(geolocation, 'complete', result => {
            //   if (this.params.page !== 1) {
            //     this.params.page = 1;
            //     this.loc = result.position.lat + ", " + result.position.lng;
            //   } else {
            //     this.searchByMap(result.position.lat + ", " + result.position.lng);
            //   }
            //
            // });//返回定位信息
            // AMap.Event.addListener(geolocation, 'error', err => console.log(err));      //返回定位出错信息
          });

          let oDiv = document.querySelector(".map-box"),
            H = 0,
            Y = oDiv;
          while (Y) {
            H += Y.offsetTop;
            Y = Y.offsetParent;
          }
          window.addEventListener("scroll", () => this.handleScroll(H, oDiv));
        },
        methods: {
          handleScroll(h, o) {
            let s =
              document.body.scrollTop || document.documentElement.scrollTop;
            this.isFixed = s > h;
            this.ml = o.offsetLeft;
          },
          handleKeyUp(e) {
            if (
              (e.keyCode >= 48 && e.keyCode <= 57) ||
              (e.keyCode >= 65 && e.keyCode <= 90) ||
              e.keyCode === 8
            ) {
              // 用户输入的字符，需要自动补全
              this.getSuggestion();
            } else if (e.keyCode === 13) {
              // 用户按回车，需要搜索
              this.search();
              this.getFilter();
            } else if (e.keyCode === 38) {
              if (this.opsIndex > 0) {
                this.opsIndex--;
              } else {
                this.opsIndex = this.ops.length - 1;
              }
            } else if (e.keyCode === 40) {
              this.opsIndex = (this.opsIndex + 1) % this.ops.length;
            } else if (e.keyCode === 27) {
              this.show = false;
            }
          },
          handleSearch() {
            this.search();
            this.getFilter();
          },
          getSuggestion() {
            // 查询自动补全
            if (!this.params.key) {
              // key没有值，不去搜索了
              this.ops = [];
              return;
            }
            axios
              .get("/hotel/suggestion?key=" + this.params.key)
              .then((resp) => {
                this.ops = resp.data;
              })
              .catch((e) => {
                if (this.isTest) {
                  this.ops = ["万豪", "如家", "喜来登"];
                } else {
                  this.ops = [];
                }
                console.log(e);
              });
          },
          getFilter() {
            if (this.isTest) {
              this.filterList = this.testFilterData;
              return;
            }
            // 准备参数
            const {
              filters: { price: ps, ...fs },
              ...params
            } = this.params;
            for (_k in fs) {
              params[_k] = fs[_k];
            }
            // 处理价格
            if (ps) {
              let pArr = ps.split("-");
              params.minPrice = parseInt(pArr[0]);
              let max = parseInt(pArr[1]);
              params.maxPrice = max === 0 ? 999999 : max;
            }

            this.filterList = this.testFilterData;
            // axios
            //   .post(
            //     "/hotel/list?page=" +
            //       this.params.page +
            //       "&size=" +
            //       this.params.size +
            //       "&key=" +
            //       this.params.key +
            //       "&sortBy=" +
            //       this.params.sortBy
            //   )
            //   .then((resp) => {
            //     this.filterList = resp.data;
            //   })
            //   .catch((err) => {
            //     console.log(err);
            //     this.filterList = this.testFilterData;
            //   });
          },
          searchByMap(location) {
            // 准备参数
            const {
              filters: { price: ps, ...fs },
              ...params
            } = this.params;
            for (_k in fs) {
              params[_k] = fs[_k];
            }
            // 处理价格
            if (ps) {
              let pArr = ps.split("-");
              params.minPrice = parseInt(pArr[0]);
              let max = parseInt(pArr[1]);
              params.maxPrice = max === 0 ? 999999 : max;
            }

            // 准备地址
            if (location) {
              params.location = location;
              this.loc = location;
            }

            axios
              .get(
                "/hotel/list?page=" +
                  this.params.page +
                  "&size=" +
                  this.params.size +
                  "&key=" +
                  this.params.key +
                  "&sortBy=" +
                  this.params.sortBy +
                  "&location=" +
                  this.loc
              )
              .then((resp) => {
                this.hotels = resp.data.hotels;
                this.total = resp.data.total;

                if (this.total % 5 === 0) {
                  this.totalPage = this.total / 5;
                } else {
                  this.totalPage = Math.ceil(this.total / 5);
                }

                if (location) {
                  this.setMapCenter(location);
                } else if (this.hotels && this.hotels.length > 0) {
                  this.setMapCenter(this.hotels[0].location);
                }
                this.initMarker();
              })
              .catch((err) => {
                console.log(err);
              });
          },
          search(location) {
            // 发送ajax
            this.searchByMap(location);
          },
          prePage() {
            if (this.params.page > 1) {
              this.params.page--;
            }
          },
          nextPage() {
            if (this.params.page < this.totalPage) {
              this.params.page++;
            }
          },
          clickPrice(min, max) {
            this.params.minPrice = min;
            this.params.maxPrice = max;
          },
          clickFilter(key, option) {
            this.loc = "";
            const { ...obj } = this.params.filters;
            obj[key] = option;
            this.params.filters = obj;
          },
          deleteFilter(k) {
            this.loc = "";
            const { ...obj } = this.params.filters;
            delete obj[k];
            this.params.filters = obj;
          },
          location(loc) {
            let arr = loc.split(", ");
            let json = "[" + arr[1] + ", " + arr[0] + "]";
            return JSON.parse(json);
          },
          initMarker() {
            if (!this.loc) {
              this.map.clearMap();
            }
            this.markHotels();
          },
          setMapCenter(location) {
            this.map.setCenter(this.location(location));
          },
          markHotels() {
            this.hotels.forEach((h, i) => {
              // 将创建的点标记添加到已有的地图实例：
              let marker = new AMap.Marker({
                position: this.location(h.location), // 经纬度构成的一维数组[116.39, 39.9]
                title: h.name,
                offset: new AMap.Pixel(0, 0),
                anchor: "bottom-center",
              });
              marker.vid = h.id;
              this.map.add(marker);
            });
          },
          handleMarkerFocus(h) {
            this.map.setCenter(this.location(h.location));
            let old = this.currentHotel;
            let oldMarker = this.map
              .getAllOverlays("marker")
              .find((m) => m.vid === old.id);
            if (oldMarker) {
              this.updateMarker(
                oldMarker,
                "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
                "",
                this.location(old.location),
                old.id
              );
            }

            this.currentHotel = h;
            let marker = this.map
              .getAllOverlays("marker")
              .find((m) => m.vid === h.id);
            this.updateMarker(
              marker,
              "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png",
              h.name,
              this.location(h.location),
              h.id
            );
          },
          updateMarker(marker, icon, text, position, id) {
            // 自定义点标记内容
            var markerContent = document.createElement("div");

            // 点标记中的图标
            var markerImg = document.createElement("img");
            markerImg.className = "markerlnglat";
            markerImg.src = icon;
            markerImg.setAttribute("width", "25px");
            markerImg.setAttribute("height", "34px");
            markerContent.appendChild(markerImg);

            // 点标记中的文本
            if (text) {
              var markerSpan = document.createElement("span");
              markerSpan.className = "marker";
              markerSpan.innerHTML = text;
              markerContent.appendChild(markerSpan);
            }

            marker.setContent(markerContent);
            marker.setPosition(position);
            marker.vid = id;
          },
          getGeoLoc() {
            this.loading = true;
            this.geolocation.getCurrentPosition((status, result) => {
              this.loading = false;
              if (status === "complete") {
                console.log("successs");
                // https://a.amap.com/jsapi/static/image/plugin/point.png
                this.addMaker(
                  "//a.amap.com/jsapi/static/image/plugin/point.png",
                  result.position.lng,
                  result.position.lat
                );
                if (this.params.page !== 1) {
                  this.params.page = 1;
                  this.loc = result.position.lat + ", " + result.position.lng;
                } else {
                  console.log(result.position.lat + ", " + result.position.lng);
                  this.searchByMap(
                    result.position.lat + ", " + result.position.lng
                  );
                }
              } else {
                console.log("err", status);
              }
            });
          },
          addMaker(iconUrl, lng, lat) {
            // 创建 AMap.Icon 实例：
            let icon = new AMap.Icon({
              size: new AMap.Size(25, 25), // 图标尺寸
              image: iconUrl, // Icon的图像
              imageOffset: new AMap.Pixel(0, 0), // 图像相对展示区域的偏移量，适于雪碧图等
              imageSize: new AMap.Size(25, 25), // 根据所设置的大小拉伸或压缩图片
            });

            // 将 Icon 实例添加到 marker 上:
            let marker = new AMap.Marker({
              position: new AMap.LngLat(lng, lat),
              offset: new AMap.Pixel(0, 0),
              icon: icon, // 添加 Icon 实例
              title: "北京",
              zoom: 13,
              anchor: "center",
            });
            this.map.add(marker);
          },
        },
        computed: {
          remainFilter() {
            let keys = Object.keys(this.params.filters);
            let obj = {};
            Object.keys(this.filterList).forEach((key) => {
              if (!keys.includes(key) && this.filterList[key].length > 1) {
                obj[key] = this.filterList[key];
              }
            });
            return obj;
          },
        },
      });
    </script>
  </body>
</html>
